package pseudoAssemblerCompiler.twopassassembler.view;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pseudoAssemblerCompiler.twopassassembler.controller.AbstractController;
import pseudoAssemblerCompiler.twopassassembler.controller.OperationCodeController;
import pseudoAssemblerCompiler.twopassassembler.model.assemblerAlgorithms.AvailableAssemblers;
import pseudoAssemblerCompiler.twopassassembler.view.firstpass.Console;
import pseudoAssemblerCompiler.twopassassembler.view.firstpass.codeoperationtable.CodeOperationTableImpl;
import pseudoAssemblerCompiler.twopassassembler.view.secondpass.ReferenceTable;
import pseudoAssemblerCompiler.twopassassembler.view.secondpass.SymbolicNamesTable;

import java.util.List;


/**
 * Основное окно представления
 *
 * @author Чекашов Р. И.
 */
public class TPAView implements WindowInterface, Object, IMainView {

    public static final Logger LOGGER =
            LoggerFactory.getLogger(TPAView.class);

    private OperationCodeController _controller;

    /**
     * Начальная ширина окна
     */
    public static final int SCREEN_WIDTH = 800;

    /**
     * Начальная высота окна
     */
    public static final int SCREEN_HEIGHT = 500;

    /**
     * Панель меню
     */
    private Menu _menu;

    /**
     * Панель содержащая внутри панель инструментов и нетолько
     */
    private CoolBar _coolbar;

    /**
     * Основной контейнер рабочей панели
     */
    private Composite _composite;

    public Composite getComposite() {
        return _composite;
    }

    private ToolItem _firstItem;

    private ToolItem _secondItem;

    private ToolItem _clearConsole;

    /**
     * Рабочее поле
     */
    private WorkSpace _workSpace;

    private ReferenceTable _referenceTable;

    private SymbolicNamesTable _symbolNameTable;

    private Console _console;

    private CodeOperationTableImpl _CodeOperationTableImpl;

    private Console _editor;

    List<AbstractController> _controllers;

    public TPAView(List<AbstractController> controllers) {
        _controllers = controllers;
    }

    public void setController(java.lang.Object controller) {
        if (controller instanceof OperationCodeController) {
            _controller = (OperationCodeController) controller;
            listeners();
            LOGGER.debug("Контроллер был инициализирован: {}", controller);
        } else {
            LOGGER.error("Контроллер не подходит этому представлению: {}", controller, this);
        }
    }

    /**
     * Создаём меню для главного окна
     *
     * @param aShell глав. окно
     * @return menu меню
     */
    private Menu createBarMenu(Shell aShell) {
        // Create the bar menu
        Menu menu = new Menu(aShell, SWT.BAR);

        // Create all the items in the bar menu
        MenuItem fileItem = new MenuItem(menu, SWT.CASCADE);
        fileItem.setText("File");
        MenuItem helpItem = new MenuItem(menu, SWT.CASCADE);
        helpItem.setText("Help");
        MenuItem selectAlgorithmItem = new MenuItem(menu, SWT.CASCADE);
        selectAlgorithmItem.setText("Select Assembler Algorithm");

        // Create the File item's dropdown menu
        Menu fileMenu = new Menu(menu);
        fileItem.setMenu(fileMenu);

        // Create all the items in the File dropdown menu
        MenuItem newItem = new MenuItem(fileMenu, SWT.NONE);
        newItem.setText("New");
        newItem.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                _controller.newProgram();
            }
        });
        MenuItem openItem = new MenuItem(fileMenu, SWT.NONE);
        openItem.setText("Open...");
        openItem.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                _controller.openProgram();
            }
        });
        MenuItem saveItem = new MenuItem(fileMenu, SWT.NONE);
        saveItem.setText("Save");
        MenuItem saveAsItem = new MenuItem(fileMenu, SWT.NONE);
        saveAsItem.setText("Save As...");
        new MenuItem(fileMenu, SWT.SEPARATOR);
        MenuItem pageSetupItem = new MenuItem(fileMenu, SWT.NONE);
        pageSetupItem.setText("Page Setup...");
        MenuItem printItem = new MenuItem(fileMenu, SWT.NONE);
        printItem.setText("Print...");
        new MenuItem(fileMenu, SWT.SEPARATOR);
        MenuItem exitItem = new MenuItem(fileMenu, SWT.NONE);
        exitItem.setText("Exit");

        Menu selectAlgorithmMenu = new Menu(menu);
        selectAlgorithmItem.setMenu(selectAlgorithmMenu);

        final MenuItem assemblerItem1 = new MenuItem(selectAlgorithmMenu, SWT.RADIO);
        assemblerItem1.setText("Assembler 1");
        assemblerItem1.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                _controller.setAssemblerAlgorithm(AvailableAssemblers.FIRST_ASSEMBLER);
            }
        });

        MenuItem assemblerItem2 = new MenuItem(selectAlgorithmMenu, SWT.RADIO);
        assemblerItem2.setText("Assembler 2");
        assemblerItem2.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                _controller.setAssemblerAlgorithm(AvailableAssemblers.SECOND_ASSEMBLER);
            }
        });

        MenuItem assemblerItem3 = new MenuItem(selectAlgorithmMenu, SWT.RADIO);
        assemblerItem3.setText("Assembler 3");
        assemblerItem3.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                _controller.setAssemblerAlgorithm(AvailableAssemblers.THIRD_ASSEMBLER);
            }
        });

        return menu;
    }

    /**
     * Создаём меню инструментов для главного окна
     *
     * @param aComposite контейнер
     * @return toolBar панель инструментов
     */
    private Control createToolBar(Composite aComposite) {
        ToolBar toolBar = new ToolBar(aComposite, SWT.HORIZONTAL);
        _firstItem = new ToolItem(toolBar, SWT.PUSH);
        _firstItem.setText("Первый проход");
        _firstItem.setEnabled(false);

        new ToolItem(toolBar, SWT.SEPARATOR);
        _secondItem = new ToolItem(toolBar, SWT.PUSH);
        _secondItem.setText("Второй проход");
        _secondItem.setEnabled(false);

        new ToolItem(toolBar, SWT.SEPARATOR);
        _clearConsole = new ToolItem(toolBar, SWT.PUSH);
        _clearConsole.setText("Очистить консоль");

        return toolBar;
    }

    /**
     * Создаём панель с панелью инструментов
     *
     * @param aShell глав. окно
     * @return coolbar панель с панелью инструментов
     */
    private CoolBar createCoolBar(Shell aShell) {
        CoolBar coolbar = new CoolBar(aShell, SWT.NONE);

        // Create toolbar coolitem
        final CoolItem item = new CoolItem(coolbar, SWT.DROP_DOWN);
        item.setControl(createToolBar(coolbar));
        calcSize(item);

        // Add a listener to handle clicks on the chevron button
        item.addSelectionListener(new SelectionAdapter() {

            /**
             * Отрабатывает при перемещении панели
             * @param aEvent событие
             */
            @Override
            public void widgetSelected(SelectionEvent aEvent) {
                calcSize(item);
            }

        });
        return coolbar;
    }

    /**
     * Метод для расчета размеров элемента панели
     *
     * @param aItem элемент панели
     */
    private void calcSize(CoolItem aItem) {
        Control control = aItem.getControl();
        Point pt = control.computeSize(SWT.DEFAULT, SWT.DEFAULT);
        pt = aItem.computeSize(pt.x, pt.y);
        aItem.setSize(pt);
    }

    /**
     * Создаём содержимое главного окна
     *
     * @param aShell глав. окно
     */
    private void createContents(Shell aShell) {
        _menu = createBarMenu(aShell);
        //Menu - Устанавливаем панель меню
        aShell.setMenuBar(_menu);
        _coolbar = createCoolBar(aShell);
        _composite = new Composite(aShell, SWT.NONE);
        setWorkSpace();
    }

    private void listeners() {
        _firstItem.addSelectionListener(new SelectionAdapter() {

            public void widgetSelected(SelectionEvent event) {
                _controller.firstPassButtonPressed();
            }

        });

        _secondItem.addSelectionListener(new SelectionAdapter() {

            public void widgetSelected(SelectionEvent event) {
                _controller.secondPassButtonPressed();
            }

        });

        _clearConsole.addSelectionListener(new SelectionAdapter() {

            public void widgetSelected(SelectionEvent event) {
                _controller.clearConsole();
            }

        });
    }

    /**
     * Нажата кнопка первого прохода
     */
    private void firstPassButtonPressed() {
        if (_editor != null) {
            System.out.println(_editor.getText());
//            _controller.firstPass(_editor.getText());
        } else {
            System.out.println("Hi");
        }
    }

    public void setSecondPassTable(ReferenceTable aReferenceTable) {
        _referenceTable = aReferenceTable;
    }

    public void setWorkSpace() {
//        _workSpace = new WorkSpace(_composite);

    }

    /**
     * Располагаем элементы в определённом порядке
     *
     * @param aShell глав. окно
     */
    private void layouts(Shell aShell) {
        FormLayout layout = new FormLayout();
        aShell.setLayout(layout);
        FormData data;

        //CoolBar - меню инструментов
        data = new FormData();
        data.left = new FormAttachment(0, 0);
        //data.bottom = new FormAttachment(100, -5);
        data.right = new FormAttachment(100, 0);
        //data.height = 30;
        _coolbar.setLayoutData(data);

        //mainComposite - основной контейнер
        data = new FormData();
        data.left = new FormAttachment(0, 0);
        data.top = new FormAttachment(_coolbar, 0);
        data.bottom = new FormAttachment(100, 0);
        data.right = new FormAttachment(100, 0);
        _composite.setLayout(new FormLayout());
        _composite.setLayoutData(data);
    }

    Display display;
    Shell shell;

    public void init() {
        display = new Display();
        shell = new Shell(display);

        //создаём содержимое окна
        createContents(shell);
        //расставляем содержимое в окне
        layouts(shell);

        if (_editor != null) {
            listeners();
        }
    }

    /**
     * Создание представления
     */
    public void createView() {

        shell.setText("Двухпроходной ассемблер");
//        shell.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
        shell.setMaximized(true);
        shell.open();

        //цикл работы окна, пока не нажата кнопка закрытия
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
        display.dispose();
    }


    /**
     * Создаём элементы управления окном
     */
    public void createControls() {
        // TODO Auto-generated method stub

    }

    public void updateOperationCodeTable(List<String[]> aTable) {
        System.out.println("updateOperationCodeTable - TPAView");
    }

    public void updateSecondPassTable(List<String[]> aTable) {
        // TODO Auto-generated method stub
//        _referenceTable.fillTable(aTable);
    }

    @Override
    public void enableFirstPassButton(boolean isFirstPassAvailable) {
        _firstItem.setEnabled(isFirstPassAvailable);
    }

    @Override
    public void enableSecondPassButton(boolean isSecondPassAvailable) {
        _secondItem.setEnabled(isSecondPassAvailable);
    }

}
